package com.bdbit.ChargingStation.services;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Service
public class SimpleChargingRetryService {
    
    @Autowired
    private MqttServerService mqttServerService;
    
    // 配置参数
    @Value("${charging.retry.max-attempts:2}")
    private int maxRetryAttempts;
    
    @Value("${charging.retry.interval-seconds:10}")
    private int retryIntervalSeconds;
    
    @Value("${charging.retry.timeout-seconds:10}")
    private int timeoutSeconds;
    
    private final ConcurrentHashMap<String, RetryTaskInfo> retryTasks = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
    

    
    /**
     * 停止重发任务（收到充电桩确认时调用）
     */
    public void stopRetryTask(String orderId) {
        RetryTaskInfo taskInfo = retryTasks.remove(orderId);
        if (taskInfo != null) {
            taskInfo.cancel();
            log.info("收到充电桩确认，停止重发: orderId={}, 总共发送{}次", orderId, taskInfo.getRetryCount());
        }
    }
    
    /**
     * 处理超时情况
     */
    private void handleTimeout(RetryTaskInfo taskInfo) {
        if (taskInfo.isCancelled()) {
            return;
        }
        
        log.warn("充电指令确认超时: orderId={}, 总共重发{}次, 可能设备信号不好或故障", 
                taskInfo.getOrderId(), taskInfo.getRetryCount());
        
        retryTasks.remove(taskInfo.getOrderId());
        taskInfo.cancel();
        
        // TODO: 可以在这里添加超时处理逻辑
        // 1. 发送告警通知
        // 2. 标记设备异常
        // 3. 触发人工处理流程
    }
    
    /**
     * 处理达到最大重发次数
     */
    private void handleMaxRetryReached(RetryTaskInfo taskInfo) {
//        log.error("充电指令重发失败，达到最大重试次数: orderId={}, imei={}, 重试{}次", taskInfo.getOrderId(), taskInfo.getImei(), taskInfo.getRetryCount());
        
        retryTasks.remove(taskInfo.getOrderId());
        taskInfo.cancel();
        
        // TODO: 可以在这里添加失败处理逻辑
        // 1. 自动退款
        // 2. 设备故障标记
        // 3. 运维通知
    }
    
    /**
     * 获取当前重发任务状态
     */
    public String getRetryStatus(String orderId) {
        RetryTaskInfo taskInfo = retryTasks.get(orderId);
        if (taskInfo == null) {
            return "无重发任务";
        }
        return String.format("重发中，已发送%d次", taskInfo.getRetryCount());
    }
    
    /**
     * 重发任务信息类
     */
    private static class RetryTaskInfo {
        private final String orderId;
        private final String imei;
        private final String message;
        private final int chargingMinutes;
        private final AtomicInteger retryCount = new AtomicInteger(0);
        private volatile boolean cancelled = false;
        private ScheduledFuture<?> retryFuture;
        private ScheduledFuture<?> timeoutFuture;
        
        public RetryTaskInfo(String orderId, String imei, String message, int chargingMinutes) {
            this.orderId = orderId;
            this.imei = imei;
            this.message = message;
            this.chargingMinutes = chargingMinutes;
        }
        
        public void incrementRetryCount() {
            retryCount.incrementAndGet();
        }
        
        public int getRetryCount() {
            return retryCount.get();
        }
        
        public void cancel() {
            cancelled = true;
            if (retryFuture != null) {
                retryFuture.cancel(false);
            }
            if (timeoutFuture != null) {
                timeoutFuture.cancel(false);
            }
        }
        
        // Getters
        public String getOrderId() { return orderId; }
        public String getImei() { return imei; }
        public String getMessage() { return message; }
        public int getChargingMinutes() { return chargingMinutes; }
        public boolean isCancelled() { return cancelled; }
        
        public void setRetryFuture(ScheduledFuture<?> retryFuture) {
            this.retryFuture = retryFuture;
        }
        
        public void setTimeoutFuture(ScheduledFuture<?> timeoutFuture) {
            this.timeoutFuture = timeoutFuture;
        }
    }
}